package org.sws.domain.activity.service.quota;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.sws.domain.activity.model.aggregate.CreateQuotaOrderAggregate;
import org.sws.domain.activity.model.entity.*;
import org.sws.domain.activity.model.valobj.OrderTradeTypeVO;
import org.sws.domain.activity.repository.IActivityRepository;
import org.sws.domain.activity.service.quota.policy.TradePolicyContext;
import org.sws.domain.activity.service.quota.rule.IActivityChain;
import org.sws.domain.activity.service.quota.rule.factory.ActivityChainFactory;
import org.sws.types.enums.ResponseCode;
import org.sws.types.exception.AppException;

import java.math.BigDecimal;

/**
 * @Author sws
 * @Date 2025/3/18 21:19
 * @description: 抽奖活动服务抽象模版类
 */
@Slf4j
@RequiredArgsConstructor
public abstract class AbstractRaffleActivityQuotaService implements IRaffleActivityAccountQuotaService {

    protected final IActivityRepository activityRepository;
    protected final ActivityChainFactory activityChainFactory;
    protected final TradePolicyContext tradePolicyContext;

    @Override
    public UnpaidActivityOrderEntity creatSkuRechargeOrder(SkuRechargeEntity skuRechargeEntity) {
        String bizId = skuRechargeEntity.getBizId();
        String userId = skuRechargeEntity.getUserId();
        Long sku = skuRechargeEntity.getSku();
        if (null == sku || StringUtils.isBlank(userId) || StringUtils.isBlank(bizId)) {
            throw new AppException(ResponseCode.ILLEGAL_PARAMETER.getCode(), ResponseCode.ILLEGAL_PARAMETER.getInfo());
        }
        // 查询未支付订单「7天以内的未支付订单」
        if (OrderTradeTypeVO.credit_pay_trade.equals(skuRechargeEntity.getOrderTradeType())){
            UnpaidActivityOrderEntity unpaidCreditOrder =  activityRepository.queryUnpaidActivityOrder(skuRechargeEntity);
            if (null != unpaidCreditOrder) {
                return unpaidCreditOrder;
            }
        }
        // 1. 通过sku查询活动信息
        ActivitySkuEntity activitySkuEntity = activityRepository.queryActivitySku(sku);
        ActivityEntity activityEntity = activityRepository.queryRaffleActivityByActivityId(activitySkuEntity.getActivityId());
        ActivityCountEntity activityCountEntity = activityRepository.queryRaffleActivityCountByActivityCountId(activitySkuEntity.getActivityCountId());

        if (OrderTradeTypeVO.credit_pay_trade.equals(skuRechargeEntity.getOrderTradeType())){
            BigDecimal availableAmount = activityRepository.queryUserCreditAccountAmount(userId);
            if (availableAmount.compareTo(activitySkuEntity.getProductAmount()) < 0) {
                throw new AppException(ResponseCode.CREDIT_ACCOUNT_SURPLUS_ERROR.getCode(), ResponseCode.CREDIT_ACCOUNT_SURPLUS_ERROR.getInfo());
            }
        }
        // 2. 活动规则校验 - 责任链
        IActivityChain activityChain = activityChainFactory.createActivityChain();
        boolean success = activityChain.action(activitySkuEntity,activityEntity, activityCountEntity);
        if (!success) {
           return null;
        }
        // 3. 创建用户活动账户和活动订单
        CreateQuotaOrderAggregate createQuotaOrderAggregate = buildOrderAggregate(skuRechargeEntity, activitySkuEntity, activityEntity, activityCountEntity);
        // 4. 交易策略 - 【积分兑换，支付类订单】【返利无支付交易订单，直接充值到账】【订单状态变更交易类型策略】
        tradePolicyContext.rechargeTrade(skuRechargeEntity.getOrderTradeType().getCode(), createQuotaOrderAggregate);
        // 5. 返回活动充值id
        ActivityRechargeEntity activityRechargeEntity = createQuotaOrderAggregate.getActivityRechargeEntity();
        log.info("调整账户积分额度完成 userId:{} rechargeId:{}", activityRechargeEntity.getUserId(), activityRechargeEntity.getRechargeId());
        return UnpaidActivityOrderEntity.builder()
                .userId(userId)
                .orderId(activityRechargeEntity.getRechargeId())
                .outBusinessNo(activityRechargeEntity.getBizId())
                .payAmount(activityRechargeEntity.getPayAmount())
                .build();
    }

    protected abstract CreateQuotaOrderAggregate buildOrderAggregate(SkuRechargeEntity skuRechargeEntity, ActivitySkuEntity activitySkuEntity, ActivityEntity activityEntity, ActivityCountEntity activityCountEntity);
}
